using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using Universe.Farm.Builtin;
using Universe.Farm.Builtin.ComputerInfo;
using Universe.Farm.Builtin.LocalComputerListener;
using Universe.Farm.RemotingService;

namespace Universe.Farm.ConsoleDiscoveryProxy
{
    class Program
    {
        private static Service.Farm _farm;
        private static ConfigurationContainer _config;
        private static RemotingFarmService _service;

        static void Main(string[] args)
        {
            try
            {
                Thread.CurrentThread.Name = "Main Thread";
            }
            catch
            {
            }

            if (args.Length > 0 && args[0].ToLower() == "stress")
            {
                RunStress();
                return;
            }

            _config = CreateConfiguration(TimeSpan.FromSeconds(20));
            _farm = new Service.Farm(Program._config);
            _service = new RemotingFarmService(_config);
            _farm.Start();
            Thread monitor = new Thread(RunMonitor);
            monitor.IsBackground = true;
            monitor.Start();
            Console.ReadLine();
            _farm.Stop();
        }

        private static void RunStress()
        {
            _config = CreateConfiguration(TimeSpan.FromSeconds(0.01));
            _farm = new Service.Farm(Program._config);
            _service = new RemotingFarmService(_config);
            Thread monitor = new Thread(RunMonitor);
            monitor.IsBackground = true;
            monitor.Start();
            ThreadPool.QueueUserWorkItem(
                delegate(object state)
                    {
                        while (true)
                        {
                            _farm.Start();
                            Thread.Sleep(111);
                            _farm.Stop();
                        }
                    });

            Console.ReadLine();
            _farm.Stop();
            
        }

        private static void RunMonitor()
        {
            while(true)
            {
                // Console.SetOut(TextWriter.Null);
                Console.Clear();
                Console.WriteLine("Press enter to exit");
                List<HealthInfo> all = new List<HealthInfo>(_service.GetServices(ServicesScope.FullScope));
                List<string> computers = new List<string>();
                all.ForEach(
                    delegate(HealthInfo info)
                        {
                            if (!computers.Contains(info.Computer))
                                computers.Add(info.Computer);
                        });

                computers.Sort();
                foreach (string s in computers)
                {
                    string computer = s;
                    Console.WriteLine("{0}:", computer);
                    List<HealthInfo> services = all.FindAll(delegate(HealthInfo info) { return info.Computer == computer; });
                    services.Sort(delegate(HealthInfo x, HealthInfo y) { return x.ID.CompareTo(y.ID); });
                    foreach (HealthInfo info in services)
                    {
                        Console.WriteLine("    {0:HH:mm:ss} {1}", info.RecievedTime, info.ID);
                        if (info.ID == "ComputerInfo" && info.IsOK)
                        {
                            ComputerInfoDescription description = info.DescriptionBuffer.Get<ComputerInfoDescription>();
                            Console.WriteLine("    {0}", description);
                        }
                        if (info.ID == "LocalSqlServer" && info.IsOK)
                        {
                            MsSqlDescription description = info.DescriptionBuffer.Get<MsSqlDescription>();
                            Console.WriteLine("    {0}", description);
                        }
                    }
                }

                Thread.Sleep(3000);
            }
        }

        public static ConfigurationContainer CreateConfiguration(TimeSpan interval)
        {
            ConfigurationContainer config = new ConfigurationContainer();

            List<ServiceListenerConfiguration> listeners = new List<ServiceListenerConfiguration>();

            ServiceListenerConfiguration
                listener1 =
                    new ServiceListenerConfiguration(
                        "ComputerInfo",
                        interval,
                        new ComputerInfoHealth()),
                listener2 =
                    new ServiceListenerConfiguration(
                        "LocalSqlServer",
                        interval,
                        new MsSqlHealth());

            listeners.Add(listener1);
            listeners.Add(listener2);
            config.Register<IEnumerable<ServiceListenerConfiguration>>(delegate() { return listeners; });

            CommunicationParameters cp = CommunicationParameters.Default;
            cp.IsBroadcast = true;
            cp.IntegrityAlgorithm = CommunicationParameters.CommunicationIntegrityAlgorithm.SHA384;

            List<IPAddress> multicastAddresses;
            WmiNetworkUtils.BuildTcpIpReport(out multicastAddresses);
            foreach (var address in multicastAddresses)
                cp.PeerList.Add(address);
            
            config.Register<CommunicationParameters>(delegate { return cp; });

            return config;

        }

    }
}
